using System;
using System.ComponentModel;
using System.Linq;
using System.Xml.Linq;

namespace Code5Systems.FormMaster.Business
{
	static class ExtensionMethods
	{
		
		static public bool ElementExists(this XElement Element, string ToFind)
		{
			System.Collections.Generic.IEnumerable<XElement> result = Element.Descendants(ToFind);
			return result.Count() > 0;
		}
		
		static public bool AttributeExists(this XElement Element, string ToFind)
		{
			return !(Element.Attribute(ToFind) == null);
		}

		public static T ToEnum<T>(this string enumValue) where T : struct, IConvertible
		{
			if (!typeof(T).IsEnum)
			{
				throw new ArgumentException("T must be an enumerated type");
			}

			T myEnum = default(T);

			int intVal;
			bool intParsed = int.TryParse(enumValue, out intVal);

			foreach (var item in Enum.GetValues(typeof(T)))
			{
				if (String.IsNullOrWhiteSpace(enumValue))
				{
					Enum.TryParse(item.ToString(), out myEnum);
					break;
				}

				if (intParsed && (int)item == intVal)
				{
					Enum.TryParse(item.ToString(), out myEnum);
					break;
				}
				
				if (item.ToString() == enumValue)
				{
					Enum.TryParse(item.ToString(), out myEnum);
					break;
				}
			}

			return myEnum;
		}

		public static int EnumToInt<T>(this T enumValue) where T : struct, IConvertible
		{
			if (!typeof(T).IsEnum)
			{
				throw new ArgumentException("T must be an enumerated type");
			}

			return enumValue.ToInt32(System.Threading.Thread.CurrentThread.CurrentCulture);
		}

		public static T ToEnum<T>(this int enumValue) where T : struct, IConvertible
		{
			if (!typeof(T).IsEnum)
			{
				throw new ArgumentException("T must be an enumerated type");
			}

			T myEnum = default(T);
			foreach (var item in Enum.GetValues(typeof(T)))
			{
				if ((int)item == enumValue)
				{
					Enum.TryParse(item.ToString(), out myEnum);
					break;
				}
			}

			return myEnum;
		}

		//public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
		//{
		//	var values = from TEnum e in Enum.GetValues(typeof(TEnum))
		//				 select new { Id = e, Name = e.ToString() };

		//	return new SelectList(values, "Id", "Name", enumObj);
		//}

		public static string Description<T>(this T theEnum) where T : struct, IConvertible
		{
			var type = typeof(T);
			var memInfo = type.GetMember(theEnum.ToString());
			var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
			var description = ((DescriptionAttribute)attributes[0]).Description;
			return description;
		}
		
	}
}
